listitemmanager: Switch from "insert_before" to "insert_after" argumnet
authorBenjamin Otte <otte@redhat.com>
Fri, 28 Sep 2018 00:05:46 +0000 (02:05 +0200)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 30 May 2020 23:26:45 +0000 (19:26 -0400)
We reorder widgets start to end, so when reusing a list item, we
correctly know the previous sibling for that list item, but not the
next sibling yet. We just know the widget it should ultimately be in
front of.
So we can do a more correct guess of the list item's place in the widget
tree if we think about where to place an item like this.

Actually using this change will come in the next commit.

gtk/gtklistitemmanager.c
gtk/gtklistitemmanagerprivate.h
gtk/gtklistview.c

index cce8eda34d95f2e147277b9c1a36d7ac8e55a288..32687440b269733cf235aa465b257fc07e949665 100644 (file)
@@ -232,8 +232,8 @@ gtk_list_item_manager_change_contains (GtkListItemManagerChange *change,
  * gtk_list_item_manager_acquire_list_item:
  * @self: a #GtkListItemManager
  * @position: the row in the model to create a list item for
- * @next_sibling: the widget this widget should be inserted before or %NULL
- *     if none
+ * @prev_sibling: the widget this widget should be inserted before or %NULL
+ *     if it should be the first widget
  *
  * Creates a list item widget to use for @position. No widget may
  * yet exist that is used for @position.
@@ -249,20 +249,20 @@ gtk_list_item_manager_change_contains (GtkListItemManagerChange *change,
 GtkWidget *
 gtk_list_item_manager_acquire_list_item (GtkListItemManager *self,
                                          guint               position,
-                                         GtkWidget          *next_sibling)
+                                         GtkWidget          *prev_sibling)
 {
   GtkListItem *result;
   gpointer item;
 
   g_return_val_if_fail (GTK_IS_LIST_ITEM_MANAGER (self), NULL);
-  g_return_val_if_fail (next_sibling == NULL || GTK_IS_WIDGET (next_sibling), NULL);
+  g_return_val_if_fail (prev_sibling == NULL || GTK_IS_WIDGET (prev_sibling), NULL);
 
   result = gtk_list_item_factory_create (self->factory);
 
   item = g_list_model_get_item (self->model, position);
   gtk_list_item_factory_bind (self->factory, result, position, item);
   g_object_unref (item);
-  gtk_widget_insert_before (GTK_WIDGET (result), self->widget, next_sibling);
+  gtk_widget_insert_after (GTK_WIDGET (result), self->widget, prev_sibling);
 
   return GTK_WIDGET (result);
 }
@@ -271,8 +271,8 @@ gtk_list_item_manager_acquire_list_item (GtkListItemManager *self,
  * gtk_list_item_manager_try_acquire_list_item_from_change:
  * @self: a #GtkListItemManager
  * @position: the row in the model to create a list item for
- * @next_sibling: the widget this widget should be inserted before or %NULL
- *     if none
+ * @prev_sibling: the widget this widget should be inserted after or %NULL
+ *     if it should be the first widget
  *
  * Like gtk_list_item_manager_acquire_list_item(), but only tries to acquire list
  * items from those previously released as part of @change.
@@ -286,20 +286,20 @@ GtkWidget *
 gtk_list_item_manager_try_reacquire_list_item (GtkListItemManager       *self,
                                                GtkListItemManagerChange *change,
                                                guint                     position,
-                                               GtkWidget                *next_sibling)
+                                               GtkWidget                *prev_sibling)
 {
   GtkListItem *result;
   gpointer item;
 
   g_return_val_if_fail (GTK_IS_LIST_ITEM_MANAGER (self), NULL);
-  g_return_val_if_fail (next_sibling == NULL || GTK_IS_WIDGET (next_sibling), NULL);
+  g_return_val_if_fail (prev_sibling == NULL || GTK_IS_WIDGET (prev_sibling), NULL);
 
   /* XXX: can we avoid temporarily allocating items on failure? */
   item = g_list_model_get_item (self->model, position);
   if (g_hash_table_steal_extended (change->items, item, NULL, (gpointer *) &result))
     {
       gtk_list_item_factory_update (self->factory, result, position);
-      gtk_widget_insert_before (GTK_WIDGET (result), self->widget, next_sibling);
+      gtk_widget_insert_after (GTK_WIDGET (result), self->widget, prev_sibling);
       /* XXX: Should we let the listview do this? */
       gtk_widget_queue_resize (GTK_WIDGET (result));
     }
index cf7721bc6ce9a8e43a0d287080f78e117510f140..0f1d1bddd117e8beb60f763263a32ca42f2e201d 100644 (file)
@@ -60,12 +60,12 @@ gboolean                gtk_list_item_manager_change_contains   (GtkListItemMana
 
 GtkWidget *             gtk_list_item_manager_acquire_list_item (GtkListItemManager     *self,
                                                                  guint                   position,
-                                                                 GtkWidget              *next_sibling);
+                                                                 GtkWidget              *prev_sibling);
 GtkWidget *             gtk_list_item_manager_try_reacquire_list_item
                                                                 (GtkListItemManager     *self,
                                                                  GtkListItemManagerChange *change,
                                                                  guint                   position,
-                                                                 GtkWidget              *next_sibling);
+                                                                 GtkWidget              *prev_sibling);
 void                    gtk_list_item_manager_update_list_item  (GtkListItemManager     *self,
                                                                  GtkWidget              *item,
                                                                  guint                   position);
index 7ef2529e3eedb446fc5b61d3a8a13fd45be581d4..c9cfc7c840dcfbf8507dffe419a6b61dcaeb308e 100644 (file)
@@ -404,7 +404,7 @@ gtk_list_view_ensure_rows (GtkListView              *self,
 {
   ListRow *row, *new_row;
   guint i, offset;
-  GtkWidget *insert_before;
+  GtkWidget *insert_after;
 
   gtk_list_view_release_rows (self);
 
@@ -417,7 +417,7 @@ gtk_list_view_ensure_rows (GtkListView              *self,
       gtk_rb_tree_node_mark_dirty (row);
     }
 
-  insert_before = gtk_widget_get_first_child (GTK_WIDGET (self));
+  insert_after = NULL;
 
   for (i = self->anchor_start; i < self->anchor_end; i++)
     {
@@ -440,21 +440,21 @@ gtk_list_view_ensure_rows (GtkListView              *self,
               new_row->widget = gtk_list_item_manager_try_reacquire_list_item (self->item_manager,
                                                                                change,
                                                                                i,
-                                                                               insert_before);
+                                                                               insert_after);
             }
           if (new_row->widget == NULL)
             {
               new_row->widget = gtk_list_item_manager_acquire_list_item (self->item_manager,
                                                                          i,
-                                                                         insert_before);
+                                                                         insert_after);
             }
         }
       else
         {
           if (update_start <= i)
             gtk_list_item_manager_update_list_item (self->item_manager, new_row->widget, i);
-          insert_before = gtk_widget_get_next_sibling (new_row->widget);
         }
+      insert_after = new_row->widget;
     }
 }
 
@@ -888,18 +888,18 @@ gtk_list_view_model_items_changed_cb (GListModel  *model,
       /* The anchor was removed, do a more expensive rebuild trying to find if
        * the anchor maybe got readded somewhere else */
       ListRow *row, *new_row;
-      GtkWidget *insert_before;
+      GtkWidget *insert_after;
       guint i, offset, anchor_pos;
       
       row = gtk_list_view_get_row (self, position, &offset);
-      for (new_row = row;
+      for (new_row = gtk_rb_tree_node_get_previous (row);
            new_row && new_row->widget == NULL;
-           new_row = gtk_rb_tree_node_get_next (new_row))
-        ;
+           new_row = gtk_rb_tree_node_get_previous (new_row))
+        { }
       if (new_row)
-        insert_before = new_row->widget;
+        insert_after = new_row->widget;
       else
-        insert_before = NULL; /* we're at the end */
+        insert_after = NULL; /* we're at the start */
 
       for (i = 0; i < added; i++)
         {
@@ -908,7 +908,7 @@ gtk_list_view_model_items_changed_cb (GListModel  *model,
           widget = gtk_list_item_manager_try_reacquire_list_item (self->item_manager,
                                                                   change,
                                                                   position + i,
-                                                                  insert_before);
+                                                                  insert_after);
           if (widget == NULL)
             {
               offset++;
@@ -938,6 +938,8 @@ gtk_list_view_model_items_changed_cb (GListModel  *model,
             }
 
           new_row->widget = widget;
+          insert_after = widget;
+
           if (widget == self->anchor)
             {
               anchor_pos = position + i;